//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_exported import SotoCore

/// Service object for interacting with AWS IoTSecureTunneling service.
///
/// IoT Secure Tunneling IoT Secure Tunneling creates remote connections to devices deployed in the
/// 			field. For more information about how IoT Secure Tunneling works, see IoT
/// 				Secure Tunneling.
public struct IoTSecureTunneling: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the IoTSecureTunneling client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - middleware: Middleware chain used to edit requests before they are sent and responses before they are decoded 
    ///     - timeout: Timeout value for HTTP requests
    ///     - byteBufferAllocator: Allocator for ByteBuffers
    ///     - options: Service options
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        middleware: AWSMiddlewareProtocol? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            amzTarget: "IoTSecuredTunneling",
            serviceName: "IoTSecureTunneling",
            serviceIdentifier: "api.tunneling.iot",
            signingName: "IoTSecuredTunneling",
            serviceProtocol: .json(version: "1.1"),
            apiVersion: "2018-10-05",
            endpoint: endpoint,
            variantEndpoints: Self.variantEndpoints,
            errorType: IoTSecureTunnelingErrorType.self,
            middleware: middleware,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }




    /// FIPS and dualstack endpoints
    static var variantEndpoints: [EndpointVariantType: AWSServiceConfig.EndpointVariant] {[
        [.dualstack]: .init(endpoints: [
            "ap-east-1": "api.iot-tunneling.ap-east-1.api.aws",
            "ap-northeast-1": "api.iot-tunneling.ap-northeast-1.api.aws",
            "ap-northeast-2": "api.iot-tunneling.ap-northeast-2.api.aws",
            "ap-south-1": "api.iot-tunneling.ap-south-1.api.aws",
            "ap-southeast-1": "api.iot-tunneling.ap-southeast-1.api.aws",
            "ap-southeast-2": "api.iot-tunneling.ap-southeast-2.api.aws",
            "ca-central-1": "api.iot-tunneling.ca-central-1.api.aws",
            "cn-north-1": "api.iot-tunneling.cn-north-1.api.amazonwebservices.com.cn",
            "cn-northwest-1": "api.iot-tunneling.cn-northwest-1.api.amazonwebservices.com.cn",
            "eu-central-1": "api.iot-tunneling.eu-central-1.api.aws",
            "eu-north-1": "api.iot-tunneling.eu-north-1.api.aws",
            "eu-west-1": "api.iot-tunneling.eu-west-1.api.aws",
            "eu-west-2": "api.iot-tunneling.eu-west-2.api.aws",
            "eu-west-3": "api.iot-tunneling.eu-west-3.api.aws",
            "me-central-1": "api.iot-tunneling.me-central-1.api.aws",
            "me-south-1": "api.iot-tunneling.me-south-1.api.aws",
            "sa-east-1": "api.iot-tunneling.sa-east-1.api.aws",
            "us-east-1": "api.iot-tunneling.us-east-1.api.aws",
            "us-east-2": "api.iot-tunneling.us-east-2.api.aws",
            "us-gov-east-1": "api.iot-tunneling.us-gov-east-1.api.aws",
            "us-gov-west-1": "api.iot-tunneling.us-gov-west-1.api.aws",
            "us-west-1": "api.iot-tunneling.us-west-1.api.aws",
            "us-west-2": "api.iot-tunneling.us-west-2.api.aws"
        ]),
        [.dualstack, .fips]: .init(endpoints: [
            "ca-central-1": "api.iot-tunneling-fips.ca-central-1.api.aws",
            "us-east-1": "api.iot-tunneling-fips.us-east-1.api.aws",
            "us-east-2": "api.iot-tunneling-fips.us-east-2.api.aws",
            "us-gov-east-1": "api.iot-tunneling-fips.us-gov-east-1.api.aws",
            "us-gov-west-1": "api.iot-tunneling-fips.us-gov-west-1.api.aws",
            "us-west-1": "api.iot-tunneling-fips.us-west-1.api.aws",
            "us-west-2": "api.iot-tunneling-fips.us-west-2.api.aws"
        ]),
        [.fips]: .init(endpoints: [
            "ca-central-1": "api.tunneling.iot-fips.ca-central-1.amazonaws.com",
            "us-east-1": "api.tunneling.iot-fips.us-east-1.amazonaws.com",
            "us-east-2": "api.tunneling.iot-fips.us-east-2.amazonaws.com",
            "us-gov-east-1": "api.tunneling.iot-fips.us-gov-east-1.amazonaws.com",
            "us-gov-west-1": "api.tunneling.iot-fips.us-gov-west-1.amazonaws.com",
            "us-west-1": "api.tunneling.iot-fips.us-west-1.amazonaws.com",
            "us-west-2": "api.tunneling.iot-fips.us-west-2.amazonaws.com"
        ])
    ]}

    // MARK: API Calls

    /// Closes a tunnel identified by the unique tunnel id. When a CloseTunnel
    /// 			request is received, we close the WebSocket connections between the client and proxy
    /// 			server so no data can be transmitted. Requires permission to access the CloseTunnel action.
    @Sendable
    @inlinable
    public func closeTunnel(_ input: CloseTunnelRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> CloseTunnelResponse {
        try await self.client.execute(
            operation: "CloseTunnel", 
            path: "/tunnels/{tunnelId}", 
            httpMethod: .DELETE, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Closes a tunnel identified by the unique tunnel id. When a CloseTunnel
    /// 			request is received, we close the WebSocket connections between the client and proxy
    /// 			server so no data can be transmitted. Requires permission to access the CloseTunnel action.
    ///
    /// Parameters:
    ///   - delete: When set to true, IoT Secure Tunneling deletes the tunnel data
    ///   - tunnelId: The ID of the tunnel to close.
    ///   - logger: Logger use during operation
    @inlinable
    public func closeTunnel(
        delete: Bool? = nil,
        tunnelId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> CloseTunnelResponse {
        let input = CloseTunnelRequest(
            delete: delete, 
            tunnelId: tunnelId
        )
        return try await self.closeTunnel(input, logger: logger)
    }

    /// Gets information about a tunnel identified by the unique tunnel id. Requires permission to access the DescribeTunnel action.
    @Sendable
    @inlinable
    public func describeTunnel(_ input: DescribeTunnelRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> DescribeTunnelResponse {
        try await self.client.execute(
            operation: "DescribeTunnel", 
            path: "/tunnels/{tunnelId}", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Gets information about a tunnel identified by the unique tunnel id. Requires permission to access the DescribeTunnel action.
    ///
    /// Parameters:
    ///   - tunnelId: The tunnel to describe.
    ///   - logger: Logger use during operation
    @inlinable
    public func describeTunnel(
        tunnelId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> DescribeTunnelResponse {
        let input = DescribeTunnelRequest(
            tunnelId: tunnelId
        )
        return try await self.describeTunnel(input, logger: logger)
    }

    /// Lists the tags for the specified resource.
    @Sendable
    @inlinable
    public func listTagsForResource(_ input: ListTagsForResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListTagsForResourceResponse {
        try await self.client.execute(
            operation: "ListTagsForResource", 
            path: "/tags", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists the tags for the specified resource.
    ///
    /// Parameters:
    ///   - resourceArn: The resource ARN.
    ///   - logger: Logger use during operation
    @inlinable
    public func listTagsForResource(
        resourceArn: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListTagsForResourceResponse {
        let input = ListTagsForResourceRequest(
            resourceArn: resourceArn
        )
        return try await self.listTagsForResource(input, logger: logger)
    }

    /// List all tunnels for an Amazon Web Services account. Tunnels are listed by creation time in
    /// 			descending order, newer tunnels will be listed before older tunnels. Requires permission to access the ListTunnels action.
    @Sendable
    @inlinable
    public func listTunnels(_ input: ListTunnelsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListTunnelsResponse {
        try await self.client.execute(
            operation: "ListTunnels", 
            path: "/tunnels", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// List all tunnels for an Amazon Web Services account. Tunnels are listed by creation time in
    /// 			descending order, newer tunnels will be listed before older tunnels. Requires permission to access the ListTunnels action.
    ///
    /// Parameters:
    ///   - maxResults: The maximum number of results to return at once.
    ///   - nextToken: To retrieve the next set of results, the nextToken value from a previous response;
    ///   - thingName: The name of the IoT thing associated with the destination device.
    ///   - logger: Logger use during operation
    @inlinable
    public func listTunnels(
        maxResults: Int? = nil,
        nextToken: String? = nil,
        thingName: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListTunnelsResponse {
        let input = ListTunnelsRequest(
            maxResults: maxResults, 
            nextToken: nextToken, 
            thingName: thingName
        )
        return try await self.listTunnels(input, logger: logger)
    }

    /// Creates a new tunnel, and returns two client access tokens for clients to use to
    /// 			connect to the IoT Secure Tunneling proxy server. Requires permission to access the OpenTunnel action.
    @Sendable
    @inlinable
    public func openTunnel(_ input: OpenTunnelRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> OpenTunnelResponse {
        try await self.client.execute(
            operation: "OpenTunnel", 
            path: "/tunnels", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Creates a new tunnel, and returns two client access tokens for clients to use to
    /// 			connect to the IoT Secure Tunneling proxy server. Requires permission to access the OpenTunnel action.
    ///
    /// Parameters:
    ///   - description: A short text description of the tunnel.
    ///   - destinationConfig: The destination configuration for the OpenTunnel request.
    ///   - tags: A collection of tag metadata.
    ///   - timeoutConfig: Timeout configuration for a tunnel.
    ///   - logger: Logger use during operation
    @inlinable
    public func openTunnel(
        description: String? = nil,
        destinationConfig: DestinationConfig? = nil,
        tags: [Tag]? = nil,
        timeoutConfig: TimeoutConfig? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> OpenTunnelResponse {
        let input = OpenTunnelRequest(
            description: description, 
            destinationConfig: destinationConfig, 
            tags: tags, 
            timeoutConfig: timeoutConfig
        )
        return try await self.openTunnel(input, logger: logger)
    }

    /// Revokes the current client access token (CAT) and returns new CAT for clients to
    /// 			use when reconnecting to secure tunneling to access the same tunnel. Requires permission to access the RotateTunnelAccessToken action.  Rotating the CAT doesn't extend the tunnel duration. For example, say the tunnel
    /// 				duration is 12 hours and the tunnel has already been open for 4 hours. When you
    /// 				rotate the access tokens, the new tokens that are generated can only be used for the
    /// 				remaining 8 hours.
    @Sendable
    @inlinable
    public func rotateTunnelAccessToken(_ input: RotateTunnelAccessTokenRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> RotateTunnelAccessTokenResponse {
        try await self.client.execute(
            operation: "RotateTunnelAccessToken", 
            path: "/tunnel/{tunnelId}/rotate", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Revokes the current client access token (CAT) and returns new CAT for clients to
    /// 			use when reconnecting to secure tunneling to access the same tunnel. Requires permission to access the RotateTunnelAccessToken action.  Rotating the CAT doesn't extend the tunnel duration. For example, say the tunnel
    /// 				duration is 12 hours and the tunnel has already been open for 4 hours. When you
    /// 				rotate the access tokens, the new tokens that are generated can only be used for the
    /// 				remaining 8 hours.
    ///
    /// Parameters:
    ///   - clientMode: The mode of the client that will use the client token, which can be either the source
    ///   - destinationConfig: 
    ///   - tunnelId: The tunnel for which you want to rotate the access tokens.
    ///   - logger: Logger use during operation
    @inlinable
    public func rotateTunnelAccessToken(
        clientMode: ClientMode,
        destinationConfig: DestinationConfig? = nil,
        tunnelId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> RotateTunnelAccessTokenResponse {
        let input = RotateTunnelAccessTokenRequest(
            clientMode: clientMode, 
            destinationConfig: destinationConfig, 
            tunnelId: tunnelId
        )
        return try await self.rotateTunnelAccessToken(input, logger: logger)
    }

    /// A resource tag.
    @Sendable
    @inlinable
    public func tagResource(_ input: TagResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> TagResourceResponse {
        try await self.client.execute(
            operation: "TagResource", 
            path: "/tags", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// A resource tag.
    ///
    /// Parameters:
    ///   - resourceArn: The ARN of the resource.
    ///   - tags: The tags for the resource.
    ///   - logger: Logger use during operation
    @inlinable
    public func tagResource(
        resourceArn: String,
        tags: [Tag],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> TagResourceResponse {
        let input = TagResourceRequest(
            resourceArn: resourceArn, 
            tags: tags
        )
        return try await self.tagResource(input, logger: logger)
    }

    /// Removes a tag from a resource.
    @Sendable
    @inlinable
    public func untagResource(_ input: UntagResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> UntagResourceResponse {
        try await self.client.execute(
            operation: "UntagResource", 
            path: "/untag", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Removes a tag from a resource.
    ///
    /// Parameters:
    ///   - resourceArn: The resource ARN.
    ///   - tagKeys: The keys of the tags to remove.
    ///   - logger: Logger use during operation
    @inlinable
    public func untagResource(
        resourceArn: String,
        tagKeys: [String],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UntagResourceResponse {
        let input = UntagResourceRequest(
            resourceArn: resourceArn, 
            tagKeys: tagKeys
        )
        return try await self.untagResource(input, logger: logger)
    }
}

extension IoTSecureTunneling {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are not public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: IoTSecureTunneling, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension IoTSecureTunneling {
    /// Return PaginatorSequence for operation ``listTunnels(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listTunnelsPaginator(
        _ input: ListTunnelsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListTunnelsRequest, ListTunnelsResponse> {
        return .init(
            input: input,
            command: self.listTunnels,
            inputKey: \ListTunnelsRequest.nextToken,
            outputKey: \ListTunnelsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listTunnels(_:logger:)``.
    ///
    /// - Parameters:
    ///   - maxResults: The maximum number of results to return at once.
    ///   - thingName: The name of the IoT thing associated with the destination device.
    ///   - logger: Logger used for logging
    @inlinable
    public func listTunnelsPaginator(
        maxResults: Int? = nil,
        thingName: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListTunnelsRequest, ListTunnelsResponse> {
        let input = ListTunnelsRequest(
            maxResults: maxResults, 
            thingName: thingName
        )
        return self.listTunnelsPaginator(input, logger: logger)
    }
}

extension IoTSecureTunneling.ListTunnelsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> IoTSecureTunneling.ListTunnelsRequest {
        return .init(
            maxResults: self.maxResults,
            nextToken: token,
            thingName: self.thingName
        )
    }
}
